#include "tftspi.h"

const unsigned char china_char[][128]= 
{
 // 当(0) 前(1) 光(2) 照(3) 强(4) 度(5) ：(6)

    {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x80,0x03,0x00,0x00,0x80,0x01,0x00,0x40,0x80,0x81,0x03,0x80,0x81,0x81,0x03,0x80,0x83,0xC1,0x00,
    0x00,0x87,0x61,0x00,0x00,0x86,0x21,0x00,0x00,0x86,0x11,0x00,0x00,0x80,0x09,0x00,0x00,0x80,0x01,0x0C,0xF0,0xFF,0xFF,0x1F,0x00,0x00,0x00,0x0C,0x00,0x00,0x00,0x0C,
    0x00,0x00,0x00,0x0C,0x00,0x00,0x00,0x0C,0x00,0x00,0x00,0x0C,0x00,0x00,0x00,0x0C,0xC0,0xFF,0xFF,0x0F,0x00,0x00,0x00,0x0C,0x00,0x00,0x00,0x0C,0x00,0x00,0x00,0x0C,
    0x00,0x00,0x00,0x0C,0x00,0x00,0x00,0x0C,0x00,0x00,0x00,0x0C,0x00,0x00,0x00,0x0C,0xF8,0xFF,0xFF,0x0F,0x00,0x00,0x00,0x0C,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x00},/*"当",0*/

    {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x20,0x00,0x00,0x04,0x70,0x00,0x00,0x1C,0x30,0x00,0x00,0x18,0x10,0x00,0x00,0x18,0x08,0x00,0x00,0x10,0x04,0x18,
    0xFC,0xFF,0xFF,0x3F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x20,0x20,0x00,0x07,0xE0,0xFF,0x08,0x03,0x60,0x60,0x18,0x03,0x60,0x60,0x18,0x03,0x60,0x60,0x18,0x03,
    0x60,0x60,0x18,0x03,0xE0,0x7F,0x18,0x03,0x60,0x60,0x18,0x03,0x60,0x60,0x18,0x03,0x60,0x60,0x18,0x03,0xE0,0x7F,0x18,0x03,0x60,0x60,0x18,0x03,0x60,0x60,0x18,0x03,
    0x60,0x60,0x18,0x03,0x60,0x60,0x18,0x03,0x60,0x60,0x00,0x02,0x60,0x60,0x00,0x03,0x60,0x3C,0xF0,0x03,0x60,0x38,0xC0,0x01,0x20,0x10,0x80,0x00,0x00,0x00,0x00,0x00},/*"前",1*/

    {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x80,0x03,0x00,0x00,0x80,0x01,0x00,0x40,0x80,0x01,0x00,0x80,0x81,0x81,0x01,0x00,0x83,0xC1,0x01,
    0x00,0x86,0xC1,0x00,0x00,0x8E,0x61,0x00,0x00,0x8C,0x61,0x00,0x00,0x8C,0x21,0x00,0x00,0x80,0x11,0x08,0x00,0x80,0x09,0x0C,0xFC,0xFF,0xFF,0x1F,0x00,0x18,0x0C,0x00,
    0x00,0x18,0x0C,0x00,0x00,0x18,0x0C,0x00,0x00,0x18,0x0C,0x00,0x00,0x18,0x0C,0x00,0x00,0x08,0x0C,0x00,0x00,0x0C,0x0C,0x00,0x00,0x0C,0x0C,0x10,0x00,0x04,0x0C,0x10,
    0x00,0x06,0x0C,0x10,0x00,0x02,0x0C,0x10,0x00,0x03,0x0C,0x10,0x80,0x00,0x0C,0x30,0x60,0x00,0xFC,0x3F,0x18,0x00,0xF8,0x1F,0x06,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"光",2*/

    {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x00,0xC8,0xFF,0x0F,0xF0,0x1F,0x0C,0x0C,0x30,0x0C,0x0C,0x04,0x30,0x0C,0x0C,0x06,0x30,0x0C,0x04,0x06,
    0x30,0x0C,0x06,0x06,0x30,0x0C,0xE3,0x03,0x30,0x0C,0x81,0x03,0xF0,0x8F,0x80,0x01,0x30,0x4C,0x01,0x04,0x30,0x2C,0xFF,0x0F,0x30,0x0C,0x03,0x06,0x30,0x0C,0x03,0x06,
    0x30,0x0C,0x03,0x06,0x30,0x0C,0x03,0x06,0x30,0x0C,0x03,0x06,0xF0,0x0F,0xFF,0x07,0x30,0x0C,0x03,0x06,0x30,0x0C,0x00,0x00,0x10,0x00,0x00,0x00,0x00,0x04,0x02,0x02,
    0x20,0x08,0x0C,0x06,0x20,0x18,0x1C,0x0C,0x30,0x30,0x18,0x1C,0x38,0x30,0x18,0x18,0x38,0x30,0x18,0x18,0x18,0x10,0x00,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"照",3*/

    {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0x04,0x00,0x84,0xFF,0x0F,0xFC,0x8F,0x01,0x06,0x00,0x84,0x01,0x06,0x00,0x84,0x01,0x06,
    0x00,0x84,0x01,0x06,0x00,0x84,0xFF,0x07,0x00,0x84,0x11,0x06,0x00,0x84,0x70,0x00,0xF0,0x07,0x30,0x00,0x10,0x04,0x30,0x00,0x10,0x40,0x30,0x08,0x10,0xC0,0xFF,0x1F,
    0x18,0xC0,0x30,0x08,0x18,0xC4,0x30,0x08,0xF8,0xCF,0x30,0x08,0x08,0xC6,0x30,0x08,0x00,0xC6,0x30,0x08,0x00,0xC6,0xFF,0x0F,0x00,0xC6,0x30,0x08,0x00,0x46,0x30,0x00,
    0x00,0x06,0x30,0x04,0x00,0x02,0x30,0x0C,0x00,0x03,0x30,0x18,0x00,0x03,0x30,0x3E,0xF0,0xF1,0xFF,0x31,0xE0,0xF1,0x01,0x20,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"强",4*/

    {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x00,0x03,0x00,0x00,0x00,0x07,0x08,0x20,0x00,0x02,0x1C,0xE0,0xFF,0xFF,0x3F,0x60,0x20,0x20,0x00,
    0x60,0xE0,0xE0,0x00,0x60,0x60,0x60,0x00,0x60,0x60,0x60,0x0C,0xE0,0xFF,0xFF,0x1F,0x60,0x60,0x60,0x00,0x60,0x60,0x60,0x00,0x60,0x60,0x60,0x00,0x60,0x60,0x60,0x00,
    0x60,0xE0,0x7F,0x00,0x60,0x60,0x60,0x00,0x20,0x00,0x80,0x00,0x20,0xFC,0xFF,0x01,0x30,0x20,0xC0,0x01,0x30,0x40,0xE0,0x00,0x30,0xC0,0x60,0x00,0x10,0x80,0x30,0x00,
    0x10,0x00,0x1B,0x00,0x18,0x00,0x0E,0x00,0x08,0x00,0x1F,0x00,0x08,0xC0,0x79,0x00,0x04,0x70,0xE0,0x1F,0x04,0x0E,0x00,0x1F,0xE2,0x01,0x00,0x08,0x00,0x00,0x00,0x00},/*"度",5*/

    {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
    0x00,0x00,0x00,0x00,0xE0,0x00,0x00,0x00,0xF0,0x00,0x00,0x00,0xF0,0x00,0x00,0x00,0xE0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
    0x00,0x00,0x00,0x00,0xE0,0x00,0x00,0x00,0xF0,0x00,0x00,0x00,0xF0,0x00,0x00,0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}/*"：",6*/
};

/*===================  1.  32×32 ASCII 0~9 字模  ===================*/
/* 纵向取模，高位在下，1 表示点亮，共 64 字节/字符 */
const uint8_t asc32x32[10][64] = {
//0(0) 1(1) 2(2) 3(3) 4(4) 5(5) 6(6) 7(7) 8(8) 9(9)

{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0x03,0x60,0x04,
0x30,0x0C,0x18,0x18,0x18,0x18,0x18,0x10,0x0C,0x30,0x0C,0x30,0x0C,0x30,0x0C,0x30,
0x0C,0x30,0x0C,0x30,0x0C,0x30,0x0C,0x30,0x0C,0x30,0x0C,0x30,0x18,0x10,0x18,0x18,
0x18,0x18,0x30,0x0C,0x60,0x04,0xC0,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"0",0*/

{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x80,0x01,
0xF8,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,
0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,
0x80,0x01,0x80,0x01,0xC0,0x03,0xF8,0x1F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"1",1*/

{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xE0,0x07,0x10,0x1C,
0x08,0x18,0x04,0x30,0x04,0x30,0x0C,0x30,0x0C,0x30,0x00,0x30,0x00,0x18,0x00,0x18,
0x00,0x0C,0x00,0x06,0x00,0x03,0x80,0x01,0xC0,0x00,0x40,0x00,0x20,0x20,0x10,0x20,
0x08,0x20,0x04,0x30,0xFC,0x1F,0xFC,0x1F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"2",2*/

{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xE0,0x03,0x18,0x06,
0x0C,0x0C,0x0C,0x18,0x0C,0x18,0x0C,0x18,0x00,0x18,0x00,0x18,0x00,0x0C,0x00,0x06,
0xC0,0x03,0x00,0x0E,0x00,0x18,0x00,0x10,0x00,0x30,0x00,0x30,0x0C,0x30,0x0C,0x30,
0x0C,0x10,0x0C,0x18,0x18,0x0C,0xE0,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"3",3*/

{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x06,0x00,0x06,
0x00,0x07,0x00,0x07,0x80,0x06,0x80,0x06,0x40,0x06,0x20,0x06,0x20,0x06,0x10,0x06,
0x10,0x06,0x08,0x06,0x0C,0x06,0x04,0x06,0x02,0x06,0xFE,0x3F,0x00,0x06,0x00,0x06,
0x00,0x06,0x00,0x06,0x00,0x06,0xC0,0x3F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"4",4*/

{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF0,0x3F,0xF0,0x3F,
0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0xC8,0x07,0x28,0x0C,
0x18,0x18,0x08,0x10,0x00,0x30,0x00,0x30,0x00,0x30,0x00,0x30,0x0C,0x30,0x0C,0x30,
0x04,0x18,0x04,0x18,0x18,0x0C,0xE0,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"5",5*/

{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x07,0x60,0x18,
0x30,0x18,0x10,0x18,0x18,0x00,0x08,0x00,0x08,0x00,0x0C,0x00,0xCC,0x07,0x6C,0x0C,
0x1C,0x18,0x1C,0x10,0x0C,0x30,0x0C,0x30,0x0C,0x30,0x0C,0x30,0x0C,0x30,0x18,0x30,
0x18,0x10,0x30,0x18,0x70,0x0C,0xC0,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"6",6*/

{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF8,0x3F,0xF8,0x3F,
0x08,0x10,0x0C,0x08,0x04,0x08,0x04,0x04,0x00,0x04,0x00,0x02,0x00,0x02,0x00,0x02,
0x00,0x01,0x00,0x01,0x80,0x00,0x80,0x00,0x80,0x00,0x80,0x00,0xC0,0x00,0xC0,0x00,
0xC0,0x00,0xC0,0x00,0xC0,0x00,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"7",7*/

{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xE0,0x07,0x30,0x0C,
0x18,0x18,0x0C,0x30,0x0C,0x30,0x0C,0x30,0x1C,0x30,0x1C,0x10,0x78,0x18,0xF0,0x04,
0xE0,0x03,0x18,0x0F,0x0C,0x1E,0x0C,0x1C,0x06,0x38,0x06,0x30,0x06,0x30,0x06,0x30,
0x06,0x30,0x0C,0x18,0x18,0x0C,0xE0,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"8",8*/

{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xE0,0x03,0x18,0x04,
0x0C,0x08,0x0C,0x18,0x06,0x10,0x06,0x30,0x06,0x30,0x06,0x30,0x06,0x30,0x06,0x30,
0x0E,0x38,0x0C,0x34,0x18,0x36,0xF0,0x31,0x00,0x30,0x00,0x18,0x00,0x18,0x00,0x08,
0x0C,0x0C,0x0C,0x06,0x0C,0x03,0xF0,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}/*"9",9*/
};


/*================ 2. 16×16 中文标题字模 ================*/
static const unsigned char title_font[9][32] = {
    /* 实 */
    {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
     0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
    /* 时 */
    {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
     0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
    /* 光 */
    {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
     0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
    /* 照 */
    {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
     0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
    /* 强 */
    {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
     0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
    /* 度 */
    {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
     0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
    /* 折 */
    {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
     0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
    /* 线 */
    {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
     0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
    /* 图 */
    {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
     0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}
};

/*-------------------------------------------------
 * 函数: lcd_print_u16_mv_no_flicker
 * 功能: 在指定坐标以 32×32 字体显示 mV 值，无闪烁刷新
 * 实现: 先擦除旧数字区域，再立即绘制新数字
 *------------------------------------------------*/
void lcd_print_u16_mv(uint16_t x, uint16_t y, uint32_t value, uint32_t color)
{
    /* 最大 4 位数字 + "m" + "V" = 6 个字符 */
    char buf[6];
    uint8_t idx, len = 0;

    /* 1. 数字 → 字符串（倒序） */
    if (value == 0) buf[len++] = '0';
    else while (value) { buf[len++] = '0' + (value % 10); value /= 10; }

    /* 2. 翻成正序 */
    for (uint8_t i = 0, j = len - 1; i < j; ++i, --j) {
        char tmp = buf[i]; buf[i] = buf[j]; buf[j] = tmp;
    }

    /* 3. 追加单位 mV */
    buf[len++] = 'm';
    buf[len++] = 'V';

    /* 4. 计算实际宽度（32 像素/字符） */
    uint16_t total_w = len * 32;

    /* 5. 擦除旧数字区域：整块画黑色背景 */
    TFT_SEND_CMD(0x2A);
    TFT_SEND_DATA((x) >> 8); TFT_SEND_DATA(x);
    TFT_SEND_DATA((x + total_w - 1) >> 8); TFT_SEND_DATA(x + total_w - 1);

    TFT_SEND_CMD(0x2B);
    TFT_SEND_DATA((y) >> 8); TFT_SEND_DATA(y);
    TFT_SEND_DATA((y + 31) >> 8); TFT_SEND_DATA(y + 31);

    TFT_SEND_CMD(0x2C);
    for (uint32_t i = 0; i < total_w * 32; i++) {
        TFT_SEND_DATA(0x00); TFT_SEND_DATA(0x00); TFT_SEND_DATA(0x00);  /* 黑色背景 */
    }

    /* 6. 立即绘制新数字 */
    for (uint8_t i = 0; i < len; ++i) {
        idx = buf[i] - '0';
        if (buf[i] >= '0' && buf[i] <= '9')
            display_char32_32(x + i * 32, y, color, asc32x32[idx]);
    }
}

/*
2.0寸TFT SPI液晶显示屏。

ST7789V2芯片，引脚定义：
GPIO46  -   CS;
GPIO9   -   SCK;
GPIO10  -   SDA;
GPIO11  -   DC;
GPIO12  -   RST。

模式：
从左往右，从上往下    240*320  18bit 6 6 6 RGB 模式  高位模式。
*/

void IO_init(void)
{
    gpio_config_t gpio_init_struct = {0};

    /* CS */
    gpio_init_struct.intr_type = GPIO_INTR_DISABLE;         /* 失能引脚中断 */
    gpio_init_struct.mode = GPIO_MODE_OUTPUT;               /* 输出模式 */
    gpio_init_struct.pull_up_en = GPIO_PULLUP_ENABLE;       /* 使能上拉 */
    gpio_init_struct.pull_down_en = GPIO_PULLDOWN_ENABLE;  /* 使能下拉 */
    gpio_init_struct.pin_bit_mask = 1ull << CS_GPIO_PIN;   /* 设置的引脚的位掩码 */
    gpio_config(&gpio_init_struct);                         /* 配置GPIO */
    SPI_CS_1;                                                 /* 初始化置1 */
    /* SCK */
    gpio_init_struct.intr_type = GPIO_INTR_DISABLE;         /* 失能引脚中断 */
    gpio_init_struct.mode = GPIO_MODE_OUTPUT;               /* 输出模式 */
    gpio_init_struct.pull_up_en = GPIO_PULLUP_ENABLE;       /* 使能上拉 */
    gpio_init_struct.pull_down_en = GPIO_PULLDOWN_ENABLE;  /* 使能下拉 */
    gpio_init_struct.pin_bit_mask = 1ull << SCK_GPIO_PIN;   /* 设置的引脚的位掩码 */
    gpio_config(&gpio_init_struct);                         /* 配置GPIO */
    SPI_SCK_1;                                                 /* 初始化置1 */
    /* SDA */
    gpio_init_struct.intr_type = GPIO_INTR_DISABLE;         /* 失能引脚中断 */
    gpio_init_struct.mode = GPIO_MODE_INPUT_OUTPUT;         /* 输入输出模式 */
    gpio_init_struct.pull_up_en = GPIO_PULLUP_ENABLE;       /* 使能上拉 */
    gpio_init_struct.pull_down_en = GPIO_PULLDOWN_ENABLE;  /* 使能下拉 */
    gpio_init_struct.pin_bit_mask = 1ull << SDA_GPIO_PIN;   /* 设置的引脚的位掩码 */
    gpio_config(&gpio_init_struct);                         /* 配置GPIO */
    SPI_SDA_1;                                                 /* 初始化置1 */
    /* DC */
    gpio_init_struct.intr_type = GPIO_INTR_DISABLE;         /* 失能引脚中断 */
    gpio_init_struct.mode = GPIO_MODE_OUTPUT;               /* 输出模式 */
    gpio_init_struct.pull_up_en = GPIO_PULLUP_ENABLE;       /* 使能上拉 */
    gpio_init_struct.pull_down_en = GPIO_PULLDOWN_ENABLE;  /* 使能下拉 */
    gpio_init_struct.pin_bit_mask = 1ull << DC_GPIO_PIN;   /* 设置的引脚的位掩码 */
    gpio_config(&gpio_init_struct);                         /* 配置GPIO */
    SPI_DC_1;                                                 /* 初始化置1 */
    /* RST */
    gpio_init_struct.intr_type = GPIO_INTR_DISABLE;         /* 失能引脚中断 */
    gpio_init_struct.mode = GPIO_MODE_OUTPUT;               /* 输出模式 */
    gpio_init_struct.pull_up_en = GPIO_PULLUP_ENABLE;       /* 使能上拉 */
    gpio_init_struct.pull_down_en = GPIO_PULLDOWN_ENABLE;  /* 使能下拉 */
    gpio_init_struct.pin_bit_mask = 1ull << RST_GPIO_PIN;   /* 设置的引脚的位掩码 */
    gpio_config(&gpio_init_struct);                         /* 配置GPIO */
    SPI_RST_1;                                                 /* 初始化置1 */
    /* BL */
    gpio_init_struct.intr_type = GPIO_INTR_DISABLE;         /* 失能引脚中断 */
    gpio_init_struct.mode = GPIO_MODE_OUTPUT;               /* 输出模式 */
    gpio_init_struct.pull_up_en = GPIO_PULLUP_ENABLE;       /* 使能上拉 */
    gpio_init_struct.pull_down_en = GPIO_PULLDOWN_ENABLE;  /* 使能下拉 */
    gpio_init_struct.pin_bit_mask = 1ull << BL_GPIO_PIN;   /* 设置的引脚的位掩码 */
    gpio_config(&gpio_init_struct);                         /* 配置GPIO */
    SPI_BL_1;                                                 /* 初始化置1 */
}


/*
SPI模块发送函数
*/
void SPI_SendByte(unsigned char byte)
{
  
  unsigned char counter;
   
  for(counter=0;counter<8;counter++)
  { 
    SPI_SCK_0;
	  
    if((byte&0x80)==0)
    {
      SPI_SDA_0;
    }
    else SPI_SDA_1;
    byte=byte<<1;
	
    SPI_SCK_1;	
	
	SPI_SCK_0;
		
  } 
}

void TFT_SEND_CMD(unsigned char o_command)
  {
    SPI_DC_0;
    SPI_CS_0;
    SPI_SendByte(o_command);
    SPI_CS_1;
	 
    //SPI_DC_1;
  }
void TFT_SEND_DATA(unsigned char o_data)
  { 
    SPI_DC_1;
    SPI_CS_0;
    SPI_SendByte(o_data);
    SPI_CS_1;
	  
   }
void OLED_clear(void)
  {
    unsigned int ROW,column;
	TFT_SEND_CMD(0x2a); 		//Column address set
	TFT_SEND_DATA(0x00); 		//start column
	TFT_SEND_DATA(0x00); 
	TFT_SEND_DATA(0x00);		//end column
	TFT_SEND_DATA(0xEF);

	TFT_SEND_CMD(0x2b); 		//Row address set
	TFT_SEND_DATA(0x00); 		//start row
	TFT_SEND_DATA(0x00); 
	TFT_SEND_DATA(0x01);		//end row
	TFT_SEND_DATA(0x3F);
	  TFT_SEND_CMD(0x2C);			//Memory write
    for(ROW=0;ROW<OLED_LINE_NUMBER;ROW++)             //ROW loop
      { 
	  
          for(column=0;column<OLED_COLUMN_NUMBER;column++)	//column loop
            {
              TFT_SEND_DATA(0x00);
			  TFT_SEND_DATA(0x00);
				TFT_SEND_DATA(0x00);
            }
      }
  }
void OLED_full(unsigned long color)
  {
    unsigned int ROW,column;
	  TFT_SEND_CMD(0x2a); 		//Column address set
	TFT_SEND_DATA(0x00); 		//start column
	TFT_SEND_DATA(0x00); 
	TFT_SEND_DATA(0x00);		//end column
	TFT_SEND_DATA(0xEF);

	TFT_SEND_CMD(0x2b); 		//Row address set
	TFT_SEND_DATA(0x00); 		//start row
	TFT_SEND_DATA(0x00); 
	TFT_SEND_DATA(0x01);		//end row
	TFT_SEND_DATA(0x3F);
	  TFT_SEND_CMD(0x2C);			//Memory write
    for(ROW=0;ROW<OLED_LINE_NUMBER;ROW++)             //ROW loop
      { 
	  
	for(column=0;column<OLED_COLUMN_NUMBER ;column++)	//column loop
          {
            TFT_SEND_DATA(color>>16);
			  TFT_SEND_DATA(color>>8);
			  TFT_SEND_DATA(color);
          }
      }
  }

  /* 红橙黄绿青蓝紫黑白 */
  void OLED_Color_test(void)
  {
    unsigned int ROW,column;
	  TFT_SEND_CMD(0x2a); 		//Column address set
    TFT_SEND_DATA(0x00); 		//start column
    TFT_SEND_DATA(0x00); 
    TFT_SEND_DATA(0x00);		//end column
    TFT_SEND_DATA(0xEF);

    TFT_SEND_CMD(0x2b); 		//Row address set
    TFT_SEND_DATA(0x00); 		//start row
    TFT_SEND_DATA(0x00); 
    TFT_SEND_DATA(0x00);		//end row
    TFT_SEND_DATA(0x23);
	  TFT_SEND_CMD(0x2C);			//Memory write
    for(ROW=0;ROW<35;ROW++)             //ROW loop
    { 
        for(column=0;column<OLED_COLUMN_NUMBER ;column++)	//column loop
        {
          TFT_SEND_DATA(RED>>16);
          TFT_SEND_DATA(RED>>8);
          TFT_SEND_DATA(RED);
        }
    }

    TFT_SEND_CMD(0x2a); 		//Column address set
    TFT_SEND_DATA(0x00); 		//start column
    TFT_SEND_DATA(0x00); 
    TFT_SEND_DATA(0x00);		//end column
    TFT_SEND_DATA(0xEF);

    TFT_SEND_CMD(0x2b); 		//Row address set
    TFT_SEND_DATA(0x00); 		//start row
    TFT_SEND_DATA(0x24); 
    TFT_SEND_DATA(0x00);		//end row
    TFT_SEND_DATA(0x46);
	  TFT_SEND_CMD(0x2C);			//Memory write
    for(ROW=0;ROW<35;ROW++)             //ROW loop
    { 
        for(column=0;column<OLED_COLUMN_NUMBER ;column++)	//column loop
        {
          TFT_SEND_DATA(ORANGE>>16);
          TFT_SEND_DATA(ORANGE>>8);
          TFT_SEND_DATA(ORANGE);
        }
    }

    TFT_SEND_CMD(0x2a); 		//Column address set
    TFT_SEND_DATA(0x00); 		//start column
    TFT_SEND_DATA(0x00); 
    TFT_SEND_DATA(0x00);		//end column
    TFT_SEND_DATA(0xEF);

    TFT_SEND_CMD(0x2b); 		//Row address set
    TFT_SEND_DATA(0x00); 		//start row
    TFT_SEND_DATA(0x47); 
    TFT_SEND_DATA(0x00);		//end row
    TFT_SEND_DATA(0x69);
	  TFT_SEND_CMD(0x2C);			//Memory write
    for(ROW=0;ROW<35;ROW++)             //ROW loop
    { 
        for(column=0;column<OLED_COLUMN_NUMBER ;column++)	//column loop
        {
          TFT_SEND_DATA(YELLOW>>16);
          TFT_SEND_DATA(YELLOW>>8);
          TFT_SEND_DATA(YELLOW);
        }
    }

    TFT_SEND_CMD(0x2a); 		//Column address set
    TFT_SEND_DATA(0x00); 		//start column
    TFT_SEND_DATA(0x00); 
    TFT_SEND_DATA(0x00);		//end column
    TFT_SEND_DATA(0xEF);

    TFT_SEND_CMD(0x2b); 		//Row address set
    TFT_SEND_DATA(0x00); 		//start row
    TFT_SEND_DATA(0x6A); 
    TFT_SEND_DATA(0x00);		//end row
    TFT_SEND_DATA(0x8C);
	  TFT_SEND_CMD(0x2C);			//Memory write
    for(ROW=0;ROW<35;ROW++)             //ROW loop
    { 
        for(column=0;column<OLED_COLUMN_NUMBER ;column++)	//column loop
        {
          TFT_SEND_DATA(GREEN>>16);
          TFT_SEND_DATA(GREEN>>8);
          TFT_SEND_DATA(GREEN);
        }
    }

    TFT_SEND_CMD(0x2a); 		//Column address set
    TFT_SEND_DATA(0x00); 		//start column
    TFT_SEND_DATA(0x00); 
    TFT_SEND_DATA(0x00);		//end column
    TFT_SEND_DATA(0xEF);

    TFT_SEND_CMD(0x2b); 		//Row address set
    TFT_SEND_DATA(0x00); 		//start row
    TFT_SEND_DATA(0x8D); 
    TFT_SEND_DATA(0x00);		//end row
    TFT_SEND_DATA(0xAF);
	  TFT_SEND_CMD(0x2C);			//Memory write
    for(ROW=0;ROW<35;ROW++)             //ROW loop
    { 
        for(column=0;column<OLED_COLUMN_NUMBER ;column++)	//column loop
        {
          TFT_SEND_DATA(CYAN>>16);
          TFT_SEND_DATA(CYAN>>8);
          TFT_SEND_DATA(CYAN);
        }
    }

    TFT_SEND_CMD(0x2a); 		//Column address set
    TFT_SEND_DATA(0x00); 		//start column
    TFT_SEND_DATA(0x00); 
    TFT_SEND_DATA(0x00);		//end column
    TFT_SEND_DATA(0xEF);

    TFT_SEND_CMD(0x2b); 		//Row address set
    TFT_SEND_DATA(0x00); 		//start row
    TFT_SEND_DATA(0xB0); 
    TFT_SEND_DATA(0x00);		//end row
    TFT_SEND_DATA(0xD2);
	  TFT_SEND_CMD(0x2C);			//Memory write
    for(ROW=0;ROW<35;ROW++)             //ROW loop
    { 
        for(column=0;column<OLED_COLUMN_NUMBER ;column++)	//column loop
        {
          TFT_SEND_DATA(BLUE>>16);
          TFT_SEND_DATA(BLUE>>8);
          TFT_SEND_DATA(BLUE);
        }
    }

    TFT_SEND_CMD(0x2a); 		//Column address set
    TFT_SEND_DATA(0x00); 		//start column
    TFT_SEND_DATA(0x00); 
    TFT_SEND_DATA(0x00);		//end column
    TFT_SEND_DATA(0xEF);

    TFT_SEND_CMD(0x2b); 		//Row address set
    TFT_SEND_DATA(0x00); 		//start row
    TFT_SEND_DATA(0xD3); 
    TFT_SEND_DATA(0x00);		//end row
    TFT_SEND_DATA(0xF5);
	  TFT_SEND_CMD(0x2C);			//Memory write
    for(ROW=0;ROW<35;ROW++)             //ROW loop
    { 
        for(column=0;column<OLED_COLUMN_NUMBER ;column++)	//column loop
        {
          TFT_SEND_DATA(PURPLE>>16);
          TFT_SEND_DATA(PURPLE>>8);
          TFT_SEND_DATA(PURPLE);
        }
    }

    TFT_SEND_CMD(0x2a); 		//Column address set
    TFT_SEND_DATA(0x00); 		//start column
    TFT_SEND_DATA(0x00); 
    TFT_SEND_DATA(0x00);		//end column
    TFT_SEND_DATA(0xEF);

    TFT_SEND_CMD(0x2b); 		//Row address set
    TFT_SEND_DATA(0x00); 		//start row
    TFT_SEND_DATA(0xF6); 
    TFT_SEND_DATA(0x01);		//end row
    TFT_SEND_DATA(0x18);
	  TFT_SEND_CMD(0x2C);			//Memory write
    for(ROW=0;ROW<35;ROW++)             //ROW loop
    { 
        for(column=0;column<OLED_COLUMN_NUMBER ;column++)	//column loop
        {
          TFT_SEND_DATA(BLACK>>16);
          TFT_SEND_DATA(BLACK>>8);
          TFT_SEND_DATA(BLACK);
        }
    }

    TFT_SEND_CMD(0x2a); 		//Column address set
    TFT_SEND_DATA(0x00); 		//start column
    TFT_SEND_DATA(0x00); 
    TFT_SEND_DATA(0x00);		//end column
    TFT_SEND_DATA(0xEF);

    TFT_SEND_CMD(0x2b); 		//Row address set
    TFT_SEND_DATA(0x01); 		//start row
    TFT_SEND_DATA(0x19); 
    TFT_SEND_DATA(0x01);		//end row
    TFT_SEND_DATA(0x3F);
	  TFT_SEND_CMD(0x2C);			//Memory write
    for(ROW=0;ROW<35;ROW++)             //ROW loop
    { 
        for(column=0;column<OLED_COLUMN_NUMBER ;column++)	//column loop
        {
          TFT_SEND_DATA(WHITE>>16);
          TFT_SEND_DATA(WHITE>>8);
          TFT_SEND_DATA(WHITE);
        }
    }
}

void OLED_init(void)				////ST7789V2
  {
	SPI_SCK_0;
	SPI_RST_0;
	vTaskDelay(1000);
	SPI_RST_1;
	vTaskDelay(1000);
    TFT_SEND_CMD(0x11); 			//Sleep Out
	vTaskDelay(120);               //DELAY120ms 
	//--------------------------------ST7789S Frame rate setting----------------------------------// 
	TFT_SEND_CMD(0x2a); 		//Column address set
	TFT_SEND_DATA(0x00); 		//start column
	TFT_SEND_DATA(0x00); 
	TFT_SEND_DATA(0x00);		//end column
	TFT_SEND_DATA(0xef);

	TFT_SEND_CMD(0x2b); 		//Row address set
	TFT_SEND_DATA(0x00); 		//start row
	TFT_SEND_DATA(0x28); 
	TFT_SEND_DATA(0x01);		//end row
	TFT_SEND_DATA(0x17);

	TFT_SEND_CMD(0xb2); 		//Porch control
	TFT_SEND_DATA(0x0c); 
	TFT_SEND_DATA(0x0c); 
	TFT_SEND_DATA(0x00); 
	TFT_SEND_DATA(0x33); 
	TFT_SEND_DATA(0x33); 

	TFT_SEND_CMD(0x20); 		//Display Inversion Off

	TFT_SEND_CMD(0xb7); 		//Gate control
	TFT_SEND_DATA(0x56);   		//35
//---------------------------------ST7789S Power setting--------------------------------------// 
	TFT_SEND_CMD(0xbb); //VCOMS Setting
	TFT_SEND_DATA(0x18);  //1f

	TFT_SEND_CMD(0xc0); 		//LCM Control
	TFT_SEND_DATA(0x2c); 

	TFT_SEND_CMD(0xc2); 		//VDV and VRH Command Enable
	TFT_SEND_DATA(0x01); 

	TFT_SEND_CMD(0xc3); //VRH Set
	TFT_SEND_DATA(0x1f); //12

	TFT_SEND_CMD(0xc4); 			//VDV Setting
	TFT_SEND_DATA(0x20); 

	TFT_SEND_CMD(0xc6); 			//FR Control 2
	TFT_SEND_DATA(0x0f); 
//TFT_SEND_CMD(0xca); 
//TFT_SEND_DATA(0x0f); 
//TFT_SEND_CMD(0xc8); 
//TFT_SEND_DATA(0x08); 
//TFT_SEND_CMD(0x55); 
//TFT_SEND_DATA(0x90); 
	TFT_SEND_CMD(0xd0);  //Power Control 1
	TFT_SEND_DATA(0xa6);   //a4
	TFT_SEND_DATA(0xa1); 
//--------------------------------ST7789S gamma setting---------------------------------------// 

	TFT_SEND_CMD(0xe0); 
	TFT_SEND_DATA(0xd0); 
	TFT_SEND_DATA(0x0d); 
	TFT_SEND_DATA(0x14); 
	TFT_SEND_DATA(0x0b); 
	TFT_SEND_DATA(0x0b); 
	TFT_SEND_DATA(0x07); 
	TFT_SEND_DATA(0x3a);  
	TFT_SEND_DATA(0x44); 
	TFT_SEND_DATA(0x50); 
	TFT_SEND_DATA(0x08); 
	TFT_SEND_DATA(0x13); 
	TFT_SEND_DATA(0x13); 
	TFT_SEND_DATA(0x2d); 
	TFT_SEND_DATA(0x32); 

	TFT_SEND_CMD(0xe1); 				//Negative Voltage Gamma Contro
	TFT_SEND_DATA(0xd0); 
	TFT_SEND_DATA(0x0d); 
	TFT_SEND_DATA(0x14); 
	TFT_SEND_DATA(0x0b); 
	TFT_SEND_DATA(0x0b); 
	TFT_SEND_DATA(0x07); 
	TFT_SEND_DATA(0x3a); 
	TFT_SEND_DATA(0x44); 
	TFT_SEND_DATA(0x50); 
	TFT_SEND_DATA(0x08); 
	TFT_SEND_DATA(0x13); 
	TFT_SEND_DATA(0x13); 
	TFT_SEND_DATA(0x2d); 
	TFT_SEND_DATA(0x32);
	
	TFT_SEND_CMD(0x36); 			//Memory data access control
	TFT_SEND_DATA(0x00); 
	
	TFT_SEND_CMD(0x3A); 			//Interface pixel format
	//TFT_SEND_DATA(0x55);			//65K	
	TFT_SEND_DATA(0x66);			//262K  RGB 6 6 6

	TFT_SEND_CMD(0xe7); 			//SPI2 enable    启用2数据通道模式
	TFT_SEND_DATA(0x00); 


	TFT_SEND_CMD(0x21);			//Display inversion on
	TFT_SEND_CMD(0x29); 			//Display on
	TFT_SEND_CMD(0x2C);			//Memory write
  }

void Picture_display(const unsigned char *ptr_pic)
  {
    unsigned int ROW,column;
    TFT_SEND_CMD(0x2a); 		//Column address set
    TFT_SEND_DATA(0x00); 		//start column
    TFT_SEND_DATA(0x00); 
    TFT_SEND_DATA(0x00);		//end column
    TFT_SEND_DATA(0xEF);    //0xEF

    TFT_SEND_CMD(0x2b); 		//Row address set
    TFT_SEND_DATA(0x00); 		//start row
    TFT_SEND_DATA(0x00); 
    TFT_SEND_DATA(0x01);		//end row
    TFT_SEND_DATA(0x3F);
    TFT_SEND_CMD(0x2C);			//Memory write

    
    for(ROW=0;ROW<OLED_LINE_NUMBER;ROW++)        //ROW loop OLED_LINE_NUMBER
      {   
        for(column=0;column<OLED_COLUMN_NUMBER;column++)	//column loop  OLED_COLUMN_NUMBER
        {
          TFT_SEND_DATA(*ptr_pic++);
          TFT_SEND_DATA(*ptr_pic++);
          TFT_SEND_DATA(*ptr_pic++);
        }
      }
  }
void display_char16_16(unsigned int x,unsigned int y,unsigned long color,const unsigned char *point)
{
    unsigned int column;
    unsigned char tm=0,temp;
    TFT_SEND_CMD(0x2a); 		//Column address set
    TFT_SEND_DATA(x>>8); 		//start column
    TFT_SEND_DATA(x);
    x=x+15;
    TFT_SEND_DATA(x>>8);		//end column
    TFT_SEND_DATA(x);

    TFT_SEND_CMD(0x2b); 		//Row address set
    TFT_SEND_DATA(y>>8); 		//start row
    TFT_SEND_DATA(y); 
    y=y+15;
    TFT_SEND_DATA(y>>8);		//end row
    TFT_SEND_DATA(y);
    TFT_SEND_CMD(0x2C);			//Memory write
    
		
	for(column=0;column<32;column++)	//column loop
          {
			  temp=*point;
			  for(tm=0;tm<8;tm++)
			  {
			  if(temp&0x01)
					{
					TFT_SEND_DATA(color>>16);
					TFT_SEND_DATA(color>>8);
					TFT_SEND_DATA(color);
					}
			  else 
					{
					TFT_SEND_DATA(0);
					TFT_SEND_DATA(0);
					TFT_SEND_DATA(0);
					}
					temp>>=1;
				}
			  point++;
          
      }
}

void display_char32_32(unsigned int x, unsigned int y, unsigned long color, const unsigned char *point)
{
    unsigned int row, col, k;
    unsigned char tmp, mask;

    /* 1. 设置窗口为 32×32 */
    TFT_SEND_CMD(0x2A);         /* Column address set */
    TFT_SEND_DATA(x >> 8);
    TFT_SEND_DATA(x);
    TFT_SEND_DATA((x + 31) >> 8);
    TFT_SEND_DATA(x + 31);

    TFT_SEND_CMD(0x2B);         /* Row address set */
    TFT_SEND_DATA(y >> 8);
    TFT_SEND_DATA(y);
    TFT_SEND_DATA((y + 31) >> 8);
    TFT_SEND_DATA(y + 31);

    TFT_SEND_CMD(0x2C);         /* Memory write */

    /* 2. 逐行输出 128 字节 */
    for (row = 0; row < 32; row++)          /* 32 行 */
    {
        for (col = 0; col < 4; col++)       /* 每行 4 字节 */
        {
            tmp = *point++;                 /* 取 1 字节 */
            /* 3. 从 bit0 到 bit7 对应从左到右 8 个像素 */
            for (k = 0; k < 8; k++)
            {
                if (tmp & (1 << k))
                {
                    TFT_SEND_DATA(color >> 16);   /* R */
                    TFT_SEND_DATA(color >> 8);    /* G */
                    TFT_SEND_DATA(color);         /* B */
                }
                else
                {
                    TFT_SEND_DATA(0);             /* 背景色 = 黑 */
                    TFT_SEND_DATA(0);
                    TFT_SEND_DATA(0);
                }
            }
        }
    }
}

void Picture_ReverseDisplay(const unsigned char *ptr_pic)
{
    unsigned int ROW,column,data;
	TFT_SEND_CMD(0x2a); 		//Column address set
	TFT_SEND_DATA(0x00); 		//start column
	TFT_SEND_DATA(0x00); 
	TFT_SEND_DATA(0x00);		//end column
	TFT_SEND_DATA(0xef);

	TFT_SEND_CMD(0x2b); 		//Row address set
	TFT_SEND_DATA(0x00); 		//start row
	TFT_SEND_DATA(0x28); 
	TFT_SEND_DATA(0x01);		//end row
	TFT_SEND_DATA(0x17);
	TFT_SEND_CMD(0x2C);			//Memory write
    for(ROW=0;ROW<OLED_LINE_NUMBER;ROW++)        //ROW loop
      { 
	  
	for(column=0;column<OLED_COLUMN_NUMBER;column++)	//column loop
          {
            data=*ptr_pic++;
            data=~data;
            TFT_SEND_DATA(data);
			
          }
      }
  }


/*-------------------------------------------------
 * 函数: display_title16
 * 功能: 将 UTF-8 格式的 16×16 中文字符串居中显示
 * 参数:
 *      x,y   : 起始坐标(左上角)
 *      color : 字符颜色 RGB888
 *      str16 : UTF-8 字符串，每个汉字 3 字节
 *------------------------------------------------*/
void display_title16(uint16_t x, uint16_t y, uint32_t color, const char *str16)
{
    /* 字模已在 title_font[9][32] 中定义，按顺序对应“实时光照强度折线图” */
    static const unsigned char *font[9] = {
        title_font[0],title_font[1],title_font[2],title_font[3],
        title_font[4],title_font[5],title_font[6],title_font[7],title_font[8]
    };
    uint8_t idx = 0;
    while (*str16 && idx < 9) {
        if ((*str16 & 0x80) == 0) break;   /* 不是汉字直接退出 */
        str16 += 3;                        /* UTF-8 三字节汉字 */
        display_char16_16(x + idx * 16, y, color, font[idx]);
        idx++;
    }
}
